<!--
 * @Author: 九璃怀特 1599130621@qq.com
 * @Date: 2022-10-11 15:26:33
 * @LastEditors: 九璃怀特 1599130621@qq.com
 * @LastEditTime: 2022-10-26 17:17:09
 * @FilePath: \nonogram\src\components\nonogram\nonogramView.vue
 * @Description: 
 -->
<template>
  <div class="gramCore" ref="Core" :style="containerStyle">
    <div class="gramTop" ignore :style="topStyle">
      <template v-for="(rows, r) in arrC" :key="r">
        <div class="colList">
          <template v-for="(item, c) in maxCsum">
            <div
              class="textdom"
              :style="{
                transform: `scale(${IsPhone ? 1 : font < 10 ? font * 0.1 : 1})`,
                height: `${font}px`,
              }"
            >
              {{ rows[c] }}
            </div>
          </template>
        </div>
      </template>
    </div>
    <div class="gramLeft" ignore :style="leftStyle">
      <template v-for="(rows, r) in arrR" :key="r">
        <div class="rowList">
          <template v-for="(item, c) in maxRsum">
            <div
              class="textdom"
              :style="{
                transform: `scale(${IsPhone ? 1 : font < 10 ? font * 0.1 : 1})`,
              }"
            >
              {{ rows[c] }}
            </div>
          </template>
        </div>
      </template>
    </div>
    <template v-for="(rows, r) in props.titleNoNo" :key="r">
      <template v-for="(item, c) in rows" :key="c">
        <div
          class="gram-item"
          :style="{ padding: `${itemPidding < 1 ? 1 : itemPidding}px` }"
        >
          <div
            :style="{
              backgroundColor: item
                ? item == 1
                  ? props.colors[0]
                  : props.colors[1]
                : 'white',
            }"
          />
        </div>
      </template>
    </template>
  </div>
</template>
<script setup lang="ts">
import { computed, onBeforeMount, onMounted, PropType, ref } from "vue";
const props = defineProps({
  view: { type: Number, default: 400 },
  colors: {
    type: Array as PropType<Array<string>>,
    default: ["#000000", "#008080"],
  },
  titleNoNo: {
    type: Array as PropType<number[][]>,
    default: Array(5)
      .fill(null)
      .map((e) =>
        Array(5)
          .fill(null)
          .map((g) => Number(Math.random() > 0.5))
      ),
  },
});

const IsPhone = /mobile/i.test(navigator.userAgent);
function setRC(v: number): number {
  const F = !!(v % 5);
  if (F) v++;
  return F ? setRC(v) : v;
}
const Row = computed(() => {
  return setRC(props.titleNoNo.length);
});

const Col = computed(() => {
  let C = 5;
  props.titleNoNo.forEach((e) => {
    if (C < e.length) C = setRC(e.length);
  });
  return C;
});
const Magni = computed(() => {
  const f = Row.value > Col.value;
  return f ? Col.value / Row.value : Row.value / Col.value;
});
const gramWidth = ref(props.view);

const maxCsum = computed(() => {
  return Math.ceil(Row.value / 2);
});

const maxRsum = computed(() => {
  return Math.ceil(Col.value / 2);
});
// 字体大小
const font = computed(() => {
  const domMax = Math.floor((props.view * 0.2) / maxCsum.value);
  const size = Math.floor(((props.view * 0.6) / Row.value - 6) * 0.7);
  return domMax > size ? size : domMax;
});

const topStyle = computed(() => ({
  fontSize: `${font.value}px`,
  top: `${-gramWidth.value * 0.2 - 2}px`,
  height: `${-gramWidth.value * 0.2}px`,
}));
const leftStyle = computed(() => ({
  width: `${gramWidth.value * 0.2 * (Col.value / Row.value)}px`,
  fontSize: `${font.value}px`,
  left: `-${gramWidth.value * 0.2 * (Col.value / Row.value)}px`,
}));
const containerStyle = computed(() => ({
  gridTemplateColumns: `repeat(${Col.value}, minmax(${
    ((props.view - 2) * 0.6) / 5
  }px, 1fr))`,
  gridTemplateRows: `repeat(${Row.value}, minmax(${
    (props.view * 0.6) / 5
  }, 1fr))`,
  width: `${gramWidth.value * 0.6 * (Col.value / Row.value)}px`,
  height: `${gramWidth.value * 0.6}px`,
  margin: `${gramWidth.value * 0.2}px 0`,
}));

// 数字 行
const arrR = ref<number[][]>([]);
// 数字 列
const arrC = ref<number[][]>([]);
// 根据网格生成对应解题数字
function setNum() {
  arrR.value.length = arrC.value.length = Row.value;
  const arr = props.titleNoNo;
  for (let i = 0; i < arr.length; i++) {
    let sumR = 0;
    arrR.value[i] = [];
    for (let j = 0, l = arr[i].length; j < l; j++) {
      if (arr[i][j] == 1) {
        sumR++;
        if (j == l - 1) {
          arrR.value[i].unshift(sumR);
        }
      } else {
        if (sumR != 0) {
          arrR.value[i].unshift(sumR);
        }
        sumR = 0;
      }
    }
  }
  for (let i = 0; i < arr[0].length; i++) {
    let sumC = 0;
    arrC.value[i] = [];
    for (let j = 0, l = arr.length; j < l; j++) {
      if (arr[j][i] == 1) {
        sumC++;
        if (j == l - 1) {
          arrC.value[i].unshift(sumC);
        }
      } else {
        if (sumC != 0) {
          arrC.value[i].unshift(sumC);
        }
        sumC = 0;
      }
    }
  }
}
const Core = ref<HTMLDivElement>();
const getCoreWidth = computed(() => Core.value!.offsetWidth);
// 小方块的内边距
const itemPidding = ref(1);

onBeforeMount(setNum);
onMounted(() => {
  document.body.style.minWidth = `${getCoreWidth.value}px`;
});
defineExpose({
  getCoreWidth,
});
</script>

<style scoped lang="less">
.textdom {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gramCore {
  display: grid;
  border: 2px solid black;
  box-sizing: border-box;
  // overflow: hidden;
  position: relative;
  border-radius: 3px;
  background-color: black;
  .gramTop {
    display: flex;
    pointer-events: none;
    position: absolute;
    width: 100%;
    height: 33%;
    top: -33%;
    .colList {
      flex: 1;
      display: flex;
      flex-direction: column-reverse;
    }
  }
  .gramLeft {
    position: absolute;
    top: 0;
    display: flex;
    flex-direction: column;
    pointer-events: none;
    height: 100%;
    .rowList {
      flex: 1;
      display: flex;
      justify-content: flex-end;
      align-items: center;
      flex-direction: row-reverse;
    }
  }
  .gram-item {
    background-color: rgb(255, 255, 255);
    padding: 1px;
    margin: 1px;
    display: inline-grid;
    // border: 1px solid black;
  }
}
</style>
